package store

import (
	"file_explorer/common/consts"
	"file_explorer/common/log"
	"file_explorer/common/util"
	"file_explorer/model"
	"file_explorer/service"
	"file_explorer/service/eventbus"
	"file_explorer/service/task"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
)

// 全局上下文，单例
type GlobalContext struct {
	Window fyne.Window // 主窗口
	*eventbus.EventBus

	TabContexts []TabContext // tab上下文列表

	globalConf    *model.GlobalConf   // 全局配置
	TaskManager   *task.FeTaskManager // 任务管理器
	OpListContext *OpListContext      // 操作列表
}

// 添加Tab
func (ctx *GlobalContext) AddTab(tabCtx TabContext) {
	if tabCtx == nil {
		return
	}
	ctx.TabContexts = append(ctx.TabContexts, tabCtx)
	ctx.ProduceEvent(eventbus.EventKeyAddTab, map[string]interface{}{
		"tab_ctx": tabCtx,
	})
}

// 关闭Tab
func (ctx *GlobalContext) RemoveTab(tabItem *container.TabItem) {
	newTabContexts := make([]TabContext, 0)
	for _, oldTabContext := range ctx.TabContexts {
		if oldTabContext.GetTabItem() != tabItem {
			newTabContexts = append(newTabContexts, oldTabContext)
		}
	}
	ctx.TabContexts = newTabContexts
	ctx.TaskManager.ClearTabTasks(tabItem)
	ctx.ProduceEvent(eventbus.EventKeyRemoveTab, map[string]interface{}{
		"tab_item": tabItem,
	})
}

// 刷新FileTab如果已打开
func (ctx *GlobalContext) RefreshTabIfExists(path string) {
	log.Debug("refresh %v", path)
	for _, tabCtx := range ctx.TabContexts {
		if tabCtx.GetTabType() == consts.TabTypeFile {
			fileTabCtx := tabCtx.(*FileTabContext)
			if path == fileTabCtx.GetPath() {
				fileTabCtx.RefreshPath()
			}
		}
	}
}

func (ctx *GlobalContext) ClearInvalidFavorites() error {
	gConf := ctx.GetGlobalConf()
	validFavorites := make([]*model.Favorites, 0, len(gConf.Favorites))
	for _, favorites := range ctx.GetGlobalConf().Favorites {
		if util.PathExists(favorites.Path) {
			validFavorites = append(validFavorites, favorites)
		}
	}
	// 没有失效目录
	if len(validFavorites) == len(gConf.Favorites) {
		return nil
	}

	return ctx.UpdateGlobalConf(model.ConfKeyFavorites, validFavorites)
}

// 刷入配置文件，call回调
func (ctx *GlobalContext) UpdateGlobalConf(confKey string, confVal interface{}) error {
	ctx.ProduceEvent(eventbus.EventKeyGlobalConfUpdate, map[string]interface{}{
		"conf_key": confKey,
		"conf_val": confVal,
	})

	ctx.globalConf.SetConfByKey(confKey, confVal)

	return service.WriteGlobalConf(ctx.globalConf)
}

func (ctx *GlobalContext) GetGlobalConf() *model.GlobalConf {
	return ctx.globalConf
}

func NewGlobalContext(gConf *model.GlobalConf) *GlobalContext {
	ctx := &GlobalContext{
		EventBus:    eventbus.NewEventbus(),
		globalConf:  gConf,
		TaskManager: task.NewFeTaskManager(),
	}

	ctx.OpListContext = NewOpListContext(ctx)

	return ctx
}
